var gulp = require('gulp');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var jade = require('gulp-jade');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var declare = require('gulp-declare');
var _ = require('lodash');
var minifyCss = require('gulp-minify-css');
var plumber = require('gulp-plumber');
var beep = require('beepbeep');

var Module = function (moduleName) {
    var moduleTaskName = function (name) {
        return moduleName + '_' + name;
    };

    var exports = {};
    exports.path = function (path) {
        if (path.push) {// 数组
            return _.map(path, function (p) {
                return moduleName + "/" + p;
            });
        } else {
            return moduleName + "/" + path;
        }
    };
    exports.relativePath = function (relative, path) {
        if (path.push) {// 数组
            return _.map(path, function (p) {
                return exports.path(relative + "/" + p);
            });
        } else {
            return exports.path(relative + "/" + path);
        }
    };

    exports.task = function (name, deps, fn, addToDefault) {
        var taskName = moduleTaskName(name);
        if (addToDefault) defaultTasks.push(taskName);
        return gulp.task(taskName, deps, fn);
    };
    exports.watchTask = function (name, watchPath, deps, fn, addToDefault) {
        var taskName = moduleTaskName(name);
        if (addToDefault) defaultTasks.push(taskName);
        watchPath = exports.path(watchPath);
        watches.push(function () {
            gulp.watch(watchPath, [taskName]);
        });

        return gulp.task(taskName, deps, fn);
    };

    return exports;
};

var watches = [];
var defaultTasks = [];

function errorHandler(err) {
    beep(2);
    console.error(err.toString());
}

/*(function () {
 var backend = new Module('backend');
 backend.watchTask('coffee', "src/!**!/!*.coffee", [], function () {
 return gulp.src(backend.path(['src/!**!/!*.coffee']))
 .pipe(plumber({errorHandler: errorHandler}))
 .pipe(sourcemaps.init())
 .pipe(coffee())
 .pipe(sourcemaps.write('.'))
 .pipe(gulp.dest(backend.path('build')));
 }, true);
 })();*/

(function () {
    var frontend = new Module('frontend');
    frontend.watchTask('index_user', "src/index.jade", [], function () {
        return gulp.src(frontend.path("src/index.jade"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(jade())
            .pipe(gulp.dest(frontend.path('build')));
    }, true);

    frontend.watchTask('index_admin', "src/admin.jade", [], function () {
        return gulp.src(frontend.path("src/admin.jade"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(jade())
            .pipe(gulp.dest(frontend.path('build')));
    }, true);

    frontend.watchTask('template_guide', "src/template/start-guide/**.jade", [], function () {
        return gulp.src(frontend.path("src/template/start-guide/**.jade"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(jade({client: true}))
            .pipe(declare({namespace: 'APPT', noRedeclare: true}))
            .pipe(uglify())
            .pipe(concat('template_guide.js'))
            .pipe(gulp.dest(frontend.path('build/script')));
    }, true);

    frontend.watchTask('template_user', ["src/template/user/**.jade", "src/mixin.jade"], [], function () {
        return gulp.src(frontend.path("src/template/user/**.jade"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(jade({client: true}))
            .pipe(declare({namespace: 'APPT', noRedeclare: true}))
            .pipe(uglify())
            .pipe(concat('template.js'))
            .pipe(gulp.dest(frontend.path('build/script')));
    }, true);

    frontend.watchTask('template_admin', ["src/template/admin/**.jade", "src/mixin.jade"], [], function () {
        return gulp.src(frontend.path("src/template/admin/**.jade"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(jade({client: true}))
            .pipe(declare({namespace: 'APPT', noRedeclare: true}))
            .pipe(uglify())
            .pipe(concat('template-admin.js'))
            .pipe(gulp.dest(frontend.path('build/script')));
    }, true);

    frontend.watchTask('coffee', "src/coffee/**/**.coffee", [], function () {
        gulp.src(frontend.relativePath("src/coffee",
            ["setup.coffee", "app.coffee", "api.coffee", "user/**.coffee", "user_main.coffee"]))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(sourcemaps.init())
            .pipe(coffee())
            .pipe(uglify())
            .pipe(concat('app.min.js'))
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest(frontend.path('build/script')));

        gulp.src(frontend.relativePath("src/coffee",
            ["setup.coffee", "api.coffee", "admin/**.coffee", "admin_main.coffee"]))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(sourcemaps.init())
            .pipe(coffee())
            .pipe(uglify())
            .pipe(concat('admin.min.js'))
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest(frontend.path('build/script')));
    }, true);

    frontend.watchTask('sass', "src/sass/**.scss", [], function () {
        gulp.src(frontend.path(["src/sass/main.scss", "src/sass/common.scss"]))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(sass())
            .pipe(concat('app.css'))
            .pipe(minifyCss({compatibility: 'ie8'}))
            .pipe(gulp.dest(frontend.path('build/css')));

        gulp.src(frontend.path("src/sass/big.scss"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(sass())
            .pipe(concat('app.ie.css'))
            .pipe(minifyCss({compatibility: 'ie8'}))
            .pipe(gulp.dest(frontend.path('build/css')));

        gulp.src(frontend.path("src/sass/admin.scss"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(sass())
            .pipe(concat('admin.css'))
            .pipe(minifyCss({compatibility: 'ie8'}))
            .pipe(gulp.dest(frontend.path('build/css')));

        gulp.src(frontend.path("src/sass/admin_big.scss"))
            .pipe(plumber({errorHandler: errorHandler}))
            .pipe(sass())
            .pipe(concat('admin.ie.css'))
            .pipe(minifyCss({compatibility: 'ie8'}))
            .pipe(gulp.dest(frontend.path('build/css')))
    }, true);

    frontend.watchTask('copy_lib', "lib/**/**", [], function () {
        return gulp.src(frontend.path("lib/**/**"))
            .pipe(gulp.dest(frontend.path('build/lib')));
    }, true);
    frontend.watchTask('copy_img', "img/**", [], function () {
        return gulp.src(frontend.path("img/**"))
            .pipe(gulp.dest(frontend.path('build/img')));
    }, true);
})();

gulp.task('watch', function () {
    for (var i = 0; i < watches.length; i++) {
        watches[i]();
    }
});

gulp.task('default', defaultTasks);
